#ifndef _GAMEMODEL1SCENE_H_
#define _GAMEMODEL1SCENE_H_

#include "Scene.h"
#include "utility.h"
#include <btBulletDynamicsCommon.h>
#include "PapaNode.h"
#include "MyKinematicMotionState.h"
#include "MyMotionState.h"
#include "DotSceneLoader.h"
#include "BodyTransform.h"
#include "CharacterController.h"
#include "PCCharacterController.h"
//#include "PhysicsFactory.h"
#include "CollisionPair.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#include "../res/resource.h"
#endif

const Ogre::String BodyPartName[11] = {"Waist","Chest","Head","ArmUL","ArmLL","LegUL","LegLL","ArmUR","ArmLR","LegUR","LegLR"};

enum bodyparttypes {
	WAIST = 0,
	CHEST,
	HEAD,
	ARMUL,
	ARMLL,
	LEGUL,
	LEGLL,
	ARMUR,
	ARMLR,
	LEGUR,
	LEGLR,
	PARTS_COUNT
};

class BodyPartInfo
{
public:
	btVector3 Length;
	btTransform Center;
	btRigidBody *Body;
	Ogre::SceneNode *Node;
	btCollisionShape* Shape;
};

class BoxShape
{
public:
	btVector3 length;
	btCollisionShape* shape;
};

class GameMode1Scene : public Scene
{
private:
	static GameMode1Scene*					m_singleton;
	std::vector<CollisionPair>*				m_collisionPair;
	btDiscreteDynamicsWorld*				m_dynamicsWorld;
	btDefaultCollisionConfiguration*		m_collisionConfiguration;
	btCollisionDispatcher*					m_dispatcher;
	btBroadphaseInterface*					m_overlappingPairCache;
	btSequentialImpulseConstraintSolver*	m_solver;
	btAlignedObjectArray<btCollisionShape*>	m_collisionShapes;
	btAlignedObjectArray<btTypedConstraint*>m_constraints;
	BodyPartInfo*							KinectMan;
	BoxShape*								boxShapes;
	int										mNumEntitiesInstanced;

	PCCharacterController *pCharactor;

	Ogre::SceneNode*						PlaneNode;
	//for debug
	int totalFrame;
	int nowFrame;
	BodyTransform* bodyTrans;
	BodyTransform bodyInit;

public:
	GameMode1Scene(SceneEvnArgs evn)
		:Scene(evn){
			pCharactor = NULL;
			m_singleton = this;
			m_collisionPair = new std::vector<CollisionPair>();
			//Ogre::Quaternion a(0,1,0,0);
			//Ogre::Quaternion b(0,0,1,0);
			//Ogre::Vector3 a(1,0,0);
			//Ogre::Quaternion b(sqrt(0.5),0,0,sqrt(0.5));
			//Ogre::Vector3 q=b*a;
			//PRINT(q.getPitch()/3.14*180);
			//PRINT(q.getRoll()/3.14*180);
			//PRINT(q.getYaw()/3.14*180);
			//PRINT(q);
	}

	virtual ~GameMode1Scene()
	{
		exitPhysics();
		m_collisionPair->clear();
		delete m_collisionPair;
	}

	static GameMode1Scene& getInstance()
	{
		return (*m_singleton);
	}

	std::vector<CollisionPair>* getCollisionPair()
	{
		return m_collisionPair;
	}
	void initPhysics();
	void exitPhysics();
	void buildBoundingBox(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax);
	void buildBodyParts();
	void buildConstraints();
	virtual void createScene( void );
	void ShootBoxRamdonly();
	void AddBoundingBoxToPhysics(Ogre::AxisAlignedBox *AABB, bool isStatic, Ogre::SceneNode *node = NULL);

protected:
	virtual bool keyPressed( const OIS::KeyEvent &arg );
	virtual bool frameStarted(const Ogre::FrameEvent& evt);
	virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
	virtual bool frameEnded(const Ogre::FrameEvent& evt);
	void UpdatePhysics(float etime);
	void UpdateKinectMan(BoneData *bones);
	void DeleteObject();
	void ShootBox(Ogre::Vector3 start, Ogre::Vector3 linearVelocity, int l);
	btTypedConstraint* CreatePoint2PointConstraint(btRigidBody *a_body,btRigidBody *b_body, btVector3 *pivotPosInA, btVector3 *pivotPosInB);
	btCollisionShape* CreateSquareShape(btVector3 *vec);
	btCollisionShape* CreateBallShape(btScalar r);
	btRigidBody* CreateRigidBody(float mass, btTransform *trans, btCollisionShape *a_shape, short group, short mask, Ogre::SceneNode *node, bool useKMS = false);
	Ogre::SceneNode* AddOgreBox(btVector3 *length, Ogre::Vector3 position, Ogre::String name);
	Ogre::SceneNode* AddOgreBall(btScalar r, Ogre::Vector3 position, Ogre::String name);
	//for debug
	void readFile(std::string inputfile);
};

#endif